"""
-*- coding: utf-8 -*-
@Author  : Link
@Time    : 2022/11/25 16:02
@Site    : 
@File    : wrapper_interface.py
@Software: PyCharm
@Remark  : 
"""

import time

import func_timeout

from BenchCore.code_interface.operator_code import LoopType, StrType
from BenchCore.stdf_interface.stdf_data_class import LimitClass
from BenchUtils.log_utils import Print


def UnitTester(
        loop_times: int = 1,
        fail_break: bool = False,
):
    """
    用于调试flow的装饰器
    可以生产Log, Stdf
    UnitTester装饰器下面不能再有UnitTester装饰的函数
    """

    def decorator(func):
        def wrapper(ctx, **kwargs):
            time.sleep(0.01)
            ctx.test_lot_start()
            res = False
            for i in range(int(loop_times)):
                Print.Warning("LoopTimes->{} Start.".format(i))
                ctx.test_per_run()
                func(ctx, **kwargs)
                res = ctx.test_post_run()
                Print.Warning("LoopTimes->{} Stop@.".format(i))
                if not res and fail_break:
                    break
            time.sleep(0.01)
            return res

        return wrapper

    return decorator


def Tester(
        over_on: bool = False,
):
    """
    2024.03.25 Update: 需要加入Fail了重测的功能, 在原来的loop的基础上面, Loop有一次PASS就算PASS
    """

    def decorator(func):
        def wrapper(ctx, **kwargs) -> (bool, str):
            ctx.running_func = func.__name__

            if ctx.var.prr is None:
                return False
            if ctx.var.prr.PART_FLG.part_failed_flag():
                if not ctx.GloOverOn:
                    return False
                if not over_on:
                    return False
            ctx.var.func_pass = True
            try:
                func(ctx, **kwargs)
            except func_timeout.exceptions.FunctionTimedOut as err:
                ctx.JudgeParameters(0, LimitClass(
                    TEST_NUM=0,
                    TEST_TXT="FunctionTimedOut",
                    L_LIMIT=0.9,
                    H_LIMIT=1.1,
                    UNITS="BIT",
                    SOFT_BIN=98,
                    SOFT_BIN_NAME="FunctionTimedOut",
                    HARD_BIN=98,
                    HARD_BIN_NAME="FunctionTimedOut",
                ))
                Print.Danger(str(err))
            except Exception as err:
                ctx.JudgeParameters(0, LimitClass(
                    TEST_NUM=0,
                    TEST_TXT="EXCEPT_ERR",
                    L_LIMIT=0.9,
                    H_LIMIT=1.1,
                    UNITS="BIT",
                    SOFT_BIN=99,
                    SOFT_BIN_NAME="EXCEPT_ERR",
                    HARD_BIN=99,
                    HARD_BIN_NAME="EXCEPT_ERR",
                ))
                Print.Danger(str(err))

            # ======================================= TODO: 返回的数据用于TEST STAND PASS/FAIL判定

            return ctx.var.func_pass

        return wrapper

    return decorator


class Time:

    def __call__(self, func):
        def wrapper(ctx, *args, **kwargs):
            start = time.perf_counter()
            res = func(ctx, *args, **kwargs)
            use_time = round(time.perf_counter() - start, 3)
            Print.Info("FUNC:{} EXEC_TIME:{}.".format(func.__name__, use_time))
            return res

        return wrapper


def ErrorWrapper(
        error_mes: str,
):
    def decorator(func):
        def wrapper(ctx, **kwargs):
            try:
                return func(ctx, **kwargs)
            except Exception as err:
                ctx.RecordAppend(str(err), s_type=StrType.Danger)
                ctx.RecordAppend(error_mes)

        return wrapper

    return decorator
